package rules

import (
	"fmt"
	"regexp"
	"strings"
	"time"

	"network-firewall-go/internal/database"
	"network-firewall-go/internal/types"
)

// Engine 规则引擎
type Engine struct {
	database *database.Manager
	rules    []*types.Rule
	matchers map[string]*ConditionMatcher
}

// NewEngine 创建新的规则引擎
func NewEngine(db *database.Manager) *Engine {
	return &Engine{
		database: db,
		rules:    make([]*types.Rule, 0),
		matchers: make(map[string]*ConditionMatcher),
	}
}

// LoadRules 从数据库加载规则
func (e *Engine) LoadRules() error {
	rules, err := e.database.GetRules()
	if err != nil {
		return fmt.Errorf("加载规则失败: %w", err)
	}

	e.rules = rules

	// 编译条件匹配器
	for _, rule := range rules {
		if rule.Enabled {
			matcher, err := NewConditionMatcher(rule.Conditions)
			if err != nil {
				fmt.Printf("⚠️ 编译规则条件失败 [%s]: %v\n", rule.ID, err)
				continue
			}
			e.matchers[rule.ID] = matcher
		}
	}

	fmt.Printf("✅ 已加载 %d 条规则\n", len(e.rules))
	return nil
}

// ExecuteRules 执行规则
func (e *Engine) ExecuteRules(ctx *types.RequestContext) []*types.RuleExecutionResult {
	var results []*types.RuleExecutionResult

	for _, rule := range e.rules {
		if !rule.Enabled {
			continue
		}

		result := &types.RuleExecutionResult{
			RuleID:   rule.ID,
			Matched:  false,
			Executed: false,
		}

		startTime := time.Now()

		// 检查条件匹配
		matcher, exists := e.matchers[rule.ID]
		if !exists {
			result.Error = "条件匹配器不存在"
			results = append(results, result)
			continue
		}

		matched, err := matcher.Match(ctx)
		if err != nil {
			result.Error = fmt.Sprintf("条件匹配失败: %v", err)
			results = append(results, result)
			continue
		}

		result.Matched = matched
		if !matched {
			results = append(results, result)
			continue
		}

		// 执行动作
		if err := e.executeAction(rule.Actions, ctx); err != nil {
			result.Error = fmt.Sprintf("动作执行失败: %v", err)
		} else {
			result.Executed = true
		}

		result.Duration = time.Since(startTime).Microseconds()
		results = append(results, result)
	}

	return results
}

// executeAction 执行动作
func (e *Engine) executeAction(actionCode string, ctx *types.RequestContext) error {
	// 这里可以集成JavaScript引擎（如goja）来执行用户定义的代码
	// 目前简化实现，仅支持基本的日志输出
	
	fmt.Printf("🔧 执行规则动作: %s\n", actionCode)
	
	// TODO: 集成JavaScript引擎
	// 可以使用 github.com/dop251/goja 来执行JavaScript代码
	
	return nil
}

// AddRule 添加规则
func (e *Engine) AddRule(rule *types.Rule) error {
	// 保存到数据库
	if err := e.database.SaveRule(rule); err != nil {
		return fmt.Errorf("保存规则失败: %w", err)
	}

	// 重新加载规则
	return e.LoadRules()
}

// UpdateRule 更新规则
func (e *Engine) UpdateRule(rule *types.Rule) error {
	return e.AddRule(rule) // 使用相同的逻辑
}

// DeleteRule 删除规则
func (e *Engine) DeleteRule(id string) error {
	if err := e.database.DeleteRule(id); err != nil {
		return fmt.Errorf("删除规则失败: %w", err)
	}

	// 重新加载规则
	return e.LoadRules()
}

// GetRules 获取规则列表
func (e *Engine) GetRules() []*types.Rule {
	return e.rules
}

// ConditionMatcher 条件匹配器
type ConditionMatcher struct {
	expression string
	compiled   *CompiledCondition
}

// CompiledCondition 编译后的条件
type CompiledCondition struct {
	Type     string      // "simple", "complex"
	Field    string      // 字段名
	Operator string      // 操作符
	Value    string      // 值
	Children []*CompiledCondition // 子条件
	Logic    string      // "AND", "OR"
}

// NewConditionMatcher 创建条件匹配器
func NewConditionMatcher(expression string) (*ConditionMatcher, error) {
	compiled, err := compileCondition(expression)
	if err != nil {
		return nil, err
	}

	return &ConditionMatcher{
		expression: expression,
		compiled:   compiled,
	}, nil
}

// Match 匹配条件
func (cm *ConditionMatcher) Match(ctx *types.RequestContext) (bool, error) {
	return cm.evaluateCondition(cm.compiled, ctx)
}

// evaluateCondition 评估条件
func (cm *ConditionMatcher) evaluateCondition(condition *CompiledCondition, ctx *types.RequestContext) (bool, error) {
	switch condition.Type {
	case "simple":
		return cm.evaluateSimpleCondition(condition, ctx)
	case "complex":
		return cm.evaluateComplexCondition(condition, ctx)
	default:
		return false, fmt.Errorf("未知条件类型: %s", condition.Type)
	}
}

// evaluateSimpleCondition 评估简单条件
func (cm *ConditionMatcher) evaluateSimpleCondition(condition *CompiledCondition, ctx *types.RequestContext) (bool, error) {
	fieldValue := cm.getFieldValue(condition.Field, ctx)
	
	switch condition.Operator {
	case "=", "==":
		return fieldValue == condition.Value, nil
	case "!=":
		return fieldValue != condition.Value, nil
	case "包含", "contains":
		return strings.Contains(fieldValue, condition.Value), nil
	case "不包含", "not_contains":
		return !strings.Contains(fieldValue, condition.Value), nil
	case "匹配", "matches":
		matched, err := regexp.MatchString(condition.Value, fieldValue)
		return matched, err
	default:
		return false, fmt.Errorf("未支持的操作符: %s", condition.Operator)
	}
}

// evaluateComplexCondition 评估复杂条件
func (cm *ConditionMatcher) evaluateComplexCondition(condition *CompiledCondition, ctx *types.RequestContext) (bool, error) {
	if len(condition.Children) == 0 {
		return false, fmt.Errorf("复杂条件缺少子条件")
	}

	results := make([]bool, len(condition.Children))
	for i, child := range condition.Children {
		result, err := cm.evaluateCondition(child, ctx)
		if err != nil {
			return false, err
		}
		results[i] = result
	}

	switch condition.Logic {
	case "AND", "&":
		for _, result := range results {
			if !result {
				return false, nil
			}
		}
		return true, nil
	case "OR", "|":
		for _, result := range results {
			if result {
				return true, nil
			}
		}
		return false, nil
	default:
		return false, fmt.Errorf("未支持的逻辑操作符: %s", condition.Logic)
	}
}

// getFieldValue 获取字段值
func (cm *ConditionMatcher) getFieldValue(field string, ctx *types.RequestContext) string {
	switch field {
	case "url":
		if ctx.Request != nil {
			return ctx.Request.URL
		}
	case "method":
		if ctx.Request != nil {
			return ctx.Request.Method
		}
	case "host":
		if ctx.Request != nil {
			return ctx.Request.Host
		}
	case "path":
		if ctx.Request != nil {
			return ctx.Request.Path
		}
	case "status_code":
		if ctx.Response != nil {
			return fmt.Sprintf("%d", ctx.Response.StatusCode)
		}
	case "content_type":
		if ctx.Request != nil {
			return ctx.Request.ContentType
		}
		if ctx.Response != nil {
			return ctx.Response.ContentType
		}
	case "user_agent":
		if ctx.Request != nil {
			return ctx.Request.UserAgent
		}
	}
	
	// 检查请求头
	if strings.HasPrefix(field, "header.") {
		headerName := strings.TrimPrefix(field, "header.")
		if ctx.Request != nil && ctx.Request.Headers != nil {
			return ctx.Request.Headers[headerName]
		}
	}

	return ""
}

// compileCondition 编译条件表达式
func compileCondition(expression string) (*CompiledCondition, error) {
	// 简化的条件编译器
	// 支持格式: "field operator value"
	// 例如: "url 包含 google.com"
	
	expression = strings.TrimSpace(expression)
	if expression == "" {
		return nil, fmt.Errorf("条件表达式为空")
	}

	// 检查是否包含逻辑操作符
	if strings.Contains(expression, " & ") || strings.Contains(expression, " | ") {
		return compileComplexCondition(expression)
	}

	// 简单条件
	parts := strings.Fields(expression)
	if len(parts) < 3 {
		return nil, fmt.Errorf("条件格式错误，应为: field operator value")
	}

	field := parts[0]
	operator := parts[1]
	value := strings.Join(parts[2:], " ")

	return &CompiledCondition{
		Type:     "simple",
		Field:    field,
		Operator: operator,
		Value:    value,
	}, nil
}

// compileComplexCondition 编译复杂条件
func compileComplexCondition(expression string) (*CompiledCondition, error) {
	// 简化实现，支持基本的AND/OR逻辑
	var logic string
	var parts []string

	if strings.Contains(expression, " & ") {
		logic = "AND"
		parts = strings.Split(expression, " & ")
	} else if strings.Contains(expression, " | ") {
		logic = "OR"
		parts = strings.Split(expression, " | ")
	} else {
		return nil, fmt.Errorf("复杂条件格式错误")
	}

	children := make([]*CompiledCondition, len(parts))
	for i, part := range parts {
		child, err := compileCondition(strings.TrimSpace(part))
		if err != nil {
			return nil, fmt.Errorf("编译子条件失败: %w", err)
		}
		children[i] = child
	}

	return &CompiledCondition{
		Type:     "complex",
		Logic:    logic,
		Children: children,
	}, nil
} 